package net.tv90.bfmccore.game.impl;

import net.tv90.bfmccore.code.VehicleMenuGenerator;
import net.tv90.bfmccore.game.GameBase;
import net.tv90.bfmccore.game.GameManager;
import net.tv90.bfmccore.game.ai.AISystem;
import net.tv90.bfmccore.game.commander.ConquestCommanderSystem;
import net.tv90.bfmccore.game.impl.cq.ConquestArea;
import net.tv90.bfmccore.game.impl.vehicle.IVehicleMenuGenerator;
import net.tv90.bfmccore.game.impl.vehicle.VehicleGroup;
import net.tv90.bfmccore.helper.FactionHelper;
import net.tv90.bfmccore.helper.MCHHelper;
import net.tv90.bfmccore.util.HUD.ImageShow;
import net.tv90.bfmccore.util.HUD.TextShow;
import net.tv90.bfmccore.util.vector.Vector2i;
import net.tv90.bfmccore.util.vector.Vector3i;
import org.bitterorange.flansmodslain.actions.Money;
import org.bitterorange.flansmodslain.actions.Point;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static net.tv90.bfmccore.slot.SlotHelper.giveSlot;
import static net.tv90.bfmccore.util.TimeUtil.secondsToDate;

public class ConquestGame extends GameBase {

    public Map<ConquestArea, ImageShow> conquestAreaList = new LinkedHashMap<>();

    @Override
    public void initGameSource(String mapName, String gameMode, String firstFactionName, String secondFactionName, Vector3i mainSpawnPoint, Vector3i firstFactionMainSpawnPoint, Vector3i secondFactionMainSpawnPoint, List<ConquestArea> list) {
        super.initGameSource(mapName, gameMode, firstFactionName, secondFactionName, mainSpawnPoint, firstFactionMainSpawnPoint, secondFactionMainSpawnPoint, list);
        initImageSource(list);
    }

    /**
     * 将一名玩家随机传送至战区，若无阵营，传送到世界出生点
     *
     * @param p 玩家
     */
    @Override
    public void teleportSinglePlayerToBattleField(Player p) {
    }

    public void teleportVehicle(Player player, String pointIndex, String type, String vehicle) {
        String country = FactionHelper.getCountry2(player);
        if (pointIndex.equals("HQ")) {
            conquestAreaList.forEach((C, I) -> {
                if (C.index.equals("HQ") && C.originalFaction.equals(country)) {
                    C.teleportPlayerToVehicleConquestArea(player, type, vehicle);
                }
            });
        } else {
            conquestAreaList.forEach((C, I) -> {
                if (C.index.equals(pointIndex)) {
                    C.teleportPlayerToVehicleConquestArea(player, type, vehicle);
                }
            });
        }
    }

    public void initImageSource(List<ConquestArea> list) {
        ImageShow[] pointImageList = new ImageShow[list.size()];
        int imageScale = 15;
        for (int i = 0; i < list.size(); i++) {
            pointImageList[i] = new ImageShow(new Vector2i((int) (427 + imageScale / 2 + (i - (float) pointImageList.length / 2.0F) * 30), 40)
                    , new Vector2i(imageScale, imageScale), "", 1, "Point" + i);
            conquestAreaList.put(list.get(i), pointImageList[i]);
        }
    }

    @Override
    public boolean isAboutToEnd() {
        return currentTime <= 60 || firstFactionTicket <= 100 || secondFactionTicket <= 100;
    }

    @Override
    public void showGameInfo() {
        //System.out.println(mapName + " " + currentTime + " " + firstFactionName + ':' + firstFactionTicket+ ' ' + secondFactionName + ':' + secondFactionTicket);
        TextShow textShowTime = new TextShow(new Vector2i(-1, 10), secondsToDate(currentTime), 1.0D, "timeText", 1);
        TextShow textShowTicket = new TextShow(new Vector2i(-1, 20), firstFactionTicket + "-" + secondFactionTicket, 1.0D, "ticketText", 1);
        textShowTime.showToPlayers(firstFactionList);
        textShowTicket.showToPlayers(firstFactionList);
        textShowTime.showToPlayers(secondFactionList);
        textShowTicket.showToPlayers(secondFactionList);
        ImageShow image1 = new ImageShow(new Vector2i(390, 8), new Vector2i(15, 15), "[local]BattleField/" + firstFactionName + ".png", 1, "FAC1");
        ImageShow image2 = new ImageShow(new Vector2i(445, 8), new Vector2i(15, 15), "[local]BattleField/" + secondFactionName + ".png", 1, "FAC2");
        image1.showToPlayers(firstFactionList);
        image2.showToPlayers(firstFactionList);
        image1.showToPlayers(secondFactionList);
        image2.showToPlayers(secondFactionList);
        conquestAreaList.forEach((C, I) -> {
            if (!C.index.equals("HQ")) {
                String redOrBlueForFirstFaction;
                String redOrBlueForSecondFaction;
                if (C.currentFaction.equals("NEUTRALIZED")) {
                    redOrBlueForFirstFaction = "Null";
                    redOrBlueForSecondFaction = "Null";
                } else if (C.currentFaction.equals(firstFactionName)) {
                    redOrBlueForFirstFaction = "Blue";
                    redOrBlueForSecondFaction = "Red";
                } else {
                    redOrBlueForFirstFaction = "Red";
                    redOrBlueForSecondFaction = "Blue";
                }
                if (C.state == ConquestArea.ConquestAreaState.CAPTURING && !C.currentFaction.equals("NEUTRALIZED")) {
                    I.imagePath = "[local]BattleField/Point_" + redOrBlueForFirstFaction + "_" + C.index + "_Capturing.png";
                    I.showToPlayers(firstFactionList);
                    I.imagePath = "[local]BattleField/Point_" + redOrBlueForSecondFaction + "_" + C.index + "_Capturing.png";
                    I.showToPlayers(secondFactionList);
                } else {
                    I.imagePath = "[local]BattleField/Point_" + redOrBlueForFirstFaction + "_" + C.index + ".png";
                    I.showToPlayers(firstFactionList);
                    I.imagePath = "[local]BattleField/Point_" + redOrBlueForSecondFaction + "_" + C.index + ".png";
                    I.showToPlayers(secondFactionList);
                }
            }
        });
    }

    @Override
    public void showWinHUD(Set<Player> list) {
        //TextShow time = new TextShow(new Vector2i(380,150),secondsToDate(currentTime),5.0D,"time",6);
        TextShow ticket = new TextShow(new Vector2i(360, 210), firstFactionTicket + "-" + secondFactionTicket, 5.0D, "winTicket", 10);
        ImageShow image1 = new ImageShow(new Vector2i(270, 200), new Vector2i(50, 50), "[local]BattleField/" + firstFactionName + ".png", 10, "fac11");
        ImageShow image2 = new ImageShow(new Vector2i(530, 200), new Vector2i(50, 50), "[local]BattleField/" + secondFactionName + ".png", 10, "fac22");
        ImageShow win = new ImageShow(new Vector2i(-1, 150), new Vector2i(350, 50), "[local]BattleField/win.png", 10, "winHUD");
        win.showToPlayers(list);
        ticket.showToPlayers(list);
        image1.showToPlayers(list);
        image2.showToPlayers(list);
        list.forEach(p -> {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mv tp " + p.getName() + " world");
            p.playSound(p.getLocation(), "custom.bf4_victory", 100.0F, 1.0F);
            Point.add(p, 75);
            Money.give(p, 150);
            p.sendMessage("§e[管理员]对局结束，你获得75军衔积分和150游戏币的奖励");
            if (p.hasPermission("bfmc.vip2")) {
                p.sendMessage("§e[VIP战斗增益]你额外获得20军衔和40游戏币");
                Point.add(p, 20);
                Money.give(p, 40);
            }
        });
    }

    @Override
    public void showLoseHUD(Set<Player> list) {
        TextShow ticket = new TextShow(new Vector2i(360, 210), firstFactionTicket + "-" + secondFactionTicket, 5.0D, "winTicket", 10);
        ImageShow image1 = new ImageShow(new Vector2i(270, 200), new Vector2i(50, 50), "[local]BattleField/" + firstFactionName + ".png", 10, "fac11");
        ImageShow image2 = new ImageShow(new Vector2i(530, 200), new Vector2i(50, 50), "[local]BattleField/" + secondFactionName + ".png", 10, "fac22");
        ImageShow win = new ImageShow(new Vector2i(-1, 150), new Vector2i(350, 50), "[local]BattleField/lost.png", 10, "winHUD");
        win.showToPlayers(list);
        ticket.showToPlayers(list);
        image1.showToPlayers(list);
        image2.showToPlayers(list);
        list.forEach(p -> {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mv tp " + p.getName() + " world");
            p.playSound(p.getLocation(), "custom.bf4_defeat", 100.0F, 1.0F);
            Point.add(p, 50);
            Money.give(p, 100);
            p.sendMessage("§e[管理员]对局结束，你获得50军衔积分和100游戏币的奖励");
            if (p.hasPermission("bfmc.vip2")) {
                p.sendMessage("§e[VIP战斗增益]你额外获得10军衔和20游戏币");
                Point.add(p, 10);
                Money.give(p, 20);
            }
        });
    }

    @Override
    public void showSameHUD(Set<Player> list) {
        TextShow ticket = new TextShow(new Vector2i(360, 210), firstFactionTicket + "-" + secondFactionTicket, 5.0D, "winTicket", 10);
        ImageShow image1 = new ImageShow(new Vector2i(270, 200), new Vector2i(50, 50), "[local]BattleField/" + firstFactionName + ".png", 10, "fac11");
        ImageShow image2 = new ImageShow(new Vector2i(530, 200), new Vector2i(50, 50), "[local]BattleField/" + secondFactionName + ".png", 10, "fac22");
        ImageShow win = new ImageShow(new Vector2i(-1, 150), new Vector2i(350, 50), "[local]BattleField/same.png", 10, "winHUD");
        win.showToPlayers(list);
        ticket.showToPlayers(list);
        image1.showToPlayers(list);
        image2.showToPlayers(list);
        list.forEach(p -> {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mv tp " + p.getName() + " world");
            p.playSound(p.getLocation(), "custom.bf4_defeat", 100.0F, 1.0F);
            Point.add(p, 20);
            Money.give(p, 50);
            p.sendMessage("§e[管理员]你获得20军衔积分和50游戏币的奖励");
        });
    }

    @Override
    public void showExecuteHUD(Set<Player> list) {
        TextShow ticket = new TextShow(new Vector2i(360, 210), firstFactionTicket + "-" + secondFactionTicket, 5.0D, "winTicket", 10);
        ImageShow image1 = new ImageShow(new Vector2i(270, 200), new Vector2i(50, 50), "[local]BattleField/" + firstFactionName + ".png", 10, "fac11");
        ImageShow image2 = new ImageShow(new Vector2i(530, 200), new Vector2i(50, 50), "[local]BattleField/" + secondFactionName + ".png", 10, "fac22");
        ImageShow win = new ImageShow(new Vector2i(-1, 150), new Vector2i(350, 50), "[local]BattleField/same.png", 10, "winHUD");
        win.showToPlayers(list);
        ticket.showToPlayers(list);
        image1.showToPlayers(list);
        image2.showToPlayers(list);
        list.forEach(p -> {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mv tp " + p.getName() + " world");
            p.playSound(p.getLocation(), "custom.bf4_defeat", 100.0F, 1.0F);
        });
    }

    @Override
    public void tick(int tps) {
        conquestAreaList.forEach((C, I) -> {
            C.tick(tps);
            if (C.secondPerTicket > 0 && frame % C.secondPerTicket == 0 && C.state == ConquestArea.ConquestAreaState.CAPTURED) {
                subEnemyTicket(C.currentFaction, 1);
            }
        });
    }

    @Override
    public String getGameInfo() {
        return "CONQUEST " + mapName + " " + currentTime + " " + firstFactionName + ':' + firstFactionTicket + ' ' + secondFactionName + ':' + secondFactionTicket;
    }


    @Override
    public void onCustomStart() {
        commanderSystem = new ConquestCommanderSystem();
        aiSystem = new AISystem();
    }

    @Override
    public void onCustomEnd() {
        conquestAreaList.forEach((C, I) -> {
            C.initSource();
        });
    }

    @Override
    public String toString() {
        return "CONQUESTGame{" +
                "conquestAreaList=" + conquestAreaList +
                ", mapName='" + mapName + '\'' +
                ", mapName_Lang='" + mapName_Lang + '\'' +
                ", gameMode='" + gameMode + '\'' +
                ", gameType=" + gameType +
                ", firstFactionName='" + firstFactionName + '\'' +
                ", secondFactionName='" + secondFactionName + '\'' +
                ", mainSpawnPoint=" + mainSpawnPoint +
                ", firstFactionMainSpawnPoint=" + firstFactionMainSpawnPoint +
                ", secondFactionMainSpawnPoint=" + secondFactionMainSpawnPoint +
                ", maxTime=" + maxTime +
                ", currentTime=" + currentTime +
                ", maxTicket=" + maxTicket +
                ", firstFactionTicket=" + firstFactionTicket +
                ", secondFactionTicket=" + secondFactionTicket +
                ", executeEnd=" + executeEnd +
                ", isEnd=" + isEnd +
                '}';
    }

    @Override
    public void generateMenu() {
        conquestAreaList.forEach((C, I) -> {
            if (C instanceof IVehicleMenuGenerator) {
                List<VehicleGroup> firstVehicleGroups = ((IVehicleMenuGenerator) C).getFirstFactionVehicleGroup();
                List<VehicleGroup> secondVehicleGroups = ((IVehicleMenuGenerator) C).getSecondFactionVehicleGroup();
                for (VehicleGroup group : firstVehicleGroups) {
                    VehicleMenuGenerator.generateMenu(mapName + "_" + gameMode, firstFactionName, group.getType(), group.getPointIndex(), group.toMenu());
                }
                for (VehicleGroup group : secondVehicleGroups) {
                    VehicleMenuGenerator.generateMenu(mapName + "_" + gameMode, secondFactionName, group.getType(), group.getPointIndex(), group.toMenu());
                }
            }
        });
    }

    @Override
    public void deploy(Player p) {
        GameManager.inBattleFieldPlayers.add(p);
        try {
            giveSlot(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
        p.closeInventory();
    }

}
